package com.vast.ui.component.socketinterface.server.newio;

import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;

import com.vast.ui.component.socketinterface.protocol.VaSTUIComponentProtocol;
import com.vast.ui.component.socketinterface.request.Request;
import com.vast.ui.component.socketinterface.request.RequestQueue;
import com.vast.ui.component.state.Sequence;
import com.vast.ui.component.util.ConsoleLoggerSingleton;
import com.vast.ui.component.util.Logger;

public class ReceiveHandler implements Runnable {
    private SocketChannel       socketChannel;
	private final Sequence      sequence;
	private final RequestQueue  receivedQueue;
	private final Logger        logger;
	
    ReceiveHandler(SocketChannel socketChannel, Sequence sequence, RequestQueue  receivedQueue) {
        this.socketChannel = socketChannel;
        this.sequence      = sequence;
        this.receivedQueue = receivedQueue;
        this.logger        = ConsoleLoggerSingleton.getInstance();
    }
    
    public void run() {
        try {
            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
            int ch1 = 0;
            int ch2 = 0;
            Short sizeOfData = 0;
            Short command    = 0;
            Short endMarker  = 0;
                        
            while(sequence.isReceiveConnection()) {
            	int remainedByte = socketChannel.read(byteBuffer);
            	byteBuffer.flip();
            	ch1 = 0xFF & byteBuffer.get();
            	ch2 = 0xFF & byteBuffer.get();
            	sizeOfData = (short)((ch1 << 8) | (ch2));
            	
            	while(remainedByte > sizeOfData) {
            		Request request = new Request(sizeOfData - 4); // Size - sizeOfData(short) - command(short)
            		ch1 = 0xFF & byteBuffer.get();
            		ch2 = 0xFF & byteBuffer.get();
            		command = (short)((ch1 << 8) | (ch2));
            		request.command = command;          		
            		byteBuffer.get(request.data);
            		ch1 = 0xFF & byteBuffer.get();
            		ch2 = 0xFF & byteBuffer.get();
            		endMarker = (short)((ch1 << 8) | (ch2));
            		if(endMarker != VaSTUIComponentProtocol.PK_END_MARKER) {
            			logger.writeEntry("EndMarker is broken : 0x" + Integer.toHexString(endMarker));
            			return;
            		}
            		
            		receivedQueue.putRequest(request);
            		
            		remainedByte = byteBuffer.limit() - byteBuffer.position();
            		
            		if(remainedByte >= 6){
            			ch1 = 0xFF & byteBuffer.get();
                		ch2 = 0xFF & byteBuffer.get();
                		sizeOfData = (short)((ch1 << 8) | (ch2));
            		}else{
            			byteBuffer.clear();
            		}
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
            	sequence.closeReceiveConnection();
                socketChannel.close();
                logger.writeEntry("Exit Receive Handler.");
            } catch (Exception e) {}
        }
    }
}
